package com.landicorp.jd.delivery.notification

import android.annotation.SuppressLint
import android.app.*
import android.content.*
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import android.os.PowerManager
import android.text.TextUtils
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.landicorp.jd.delivery.GlobalMemoryControl
import com.landicorp.jd.eventTracking.EventTrackingService.trackingAbnormalData
import com.landicorp.jd.service.R
import com.landicorp.parameter.ParameterSetting
import com.landicorp.util.DeviceInfoUtil


/**
 * Create： zhangjunfei10 2022/2/15 10:35 上午
 * 描述：展示通知栏
 */
class ShowNotification(private val service: Service) : OnNotificationUpdate {

    /**
     * 通知栏消息点击事件的广播action
     */
    val action = "START_ACTIVITY_ACTION"

    /**
     * 通知栏builder
     */
    private lateinit var builder: NotificationCompat.Builder

    /**
     * 通知栏展示的内容分
     */
    private var customView: RemoteViews? = null

    /**
     * 通知栏消息渠道Id
     */
    private val channel = "IMPORTANCE_LOW_CHANNEL_ID"

    /**
     * 通知ID
     */
    private val notificationId = 100

    /**
     * 广播接收器
     */
    private lateinit var broadcastReceiver: BroadcastReceiver

    init {
        show()
    }

    /**
     * 模拟launcher启动应用
     */
    @SuppressLint("WrongConstant")
    fun getAppOpenIntentByPackageName(context: Context, packageName: String): Intent {
        // MainActivity完整名
        var mainAct = "com.jd.delivery.login.JDLoginActivity"
        // 根据包名寻找MainActivity
        val pkgMag: PackageManager = context.packageManager
        val intent = Intent(Intent.ACTION_MAIN)
        intent.addCategory(Intent.CATEGORY_LAUNCHER)
        intent.flags = Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED or Intent.FLAG_ACTIVITY_NEW_TASK
        val list: List<ResolveInfo> = pkgMag.queryIntentActivities(
            intent,
            PackageManager.GET_ACTIVITIES
        )
        for (i in list.indices) {
            val info: ResolveInfo = list[i]
            if (info.activityInfo.packageName.equals(packageName)) {
                mainAct = info.activityInfo.name
                break
            }
        }

        intent.component = ComponentName(packageName, mainAct)
        return intent
    }

    /**
     * 注册接收通知栏点击事件的广播
     */
    private fun registerBroadcastReceiver() {
        broadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                //收起通知栏
                context?.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))

                //判断应用是否在前台运行，如果不在前台运行，点击通知打开应用1:前台  0:APP未打开或在后台
                if (isAppAlive(service) != 1) {
                    // 埋点上报
                    trackingAbnormalData(
                        service,
                        "notification-1:通知栏——跳转到app",
                        ShowNotification::class.java.name
                    )
                    context?.startActivity(
                        getAppOpenIntentByPackageName(
                            service,
                            service.packageName
                        )
                    )
                }
            }
        }
        //注册广播
        service.registerReceiver(broadcastReceiver, IntentFilter(action))
    }

    /**
     * 开启省电白名单
     */
    @SuppressLint("InvalidWakeLockTag")
    private fun initWakeLock() {
        //在一定程度上保证进程在后端存活，并不能依赖此方法实现进程保活
        val powerManager = service.getSystemService(Context.POWER_SERVICE) as PowerManager
        val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "track upload")
        if (!wakeLock.isHeld) {
            wakeLock.acquire(1000 * 60 * 1000L)
        }
    }

    /**
     * 初始化通知
     */
    private fun initNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager =
                service.getSystemService<NotificationManager>(NotificationManager::class.java)

            val channel =
                NotificationChannel(channel, "展示派件、揽收、超时任务", NotificationManager.IMPORTANCE_LOW)
            notificationManager.createNotificationChannel(channel)
        }
    }

    /**
     * 开启前台服务，展示通知栏消息
     */
    @SuppressLint("RemoteViewLayout", "UnspecifiedImmutableFlag", "LaunchActivityFromNotification")
    fun show() {
        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) {
            return
        }
        if (DeviceInfoUtil.isPhoneDevice()) {
            val oldVersion = ParameterSetting.getInstance().getParameter("oldVersion", "")
            //首次安装存储版本信息
            if (TextUtils.isEmpty(oldVersion)) {
                ParameterSetting.getInstance()
                    .setParameter("oldVersion", GlobalMemoryControl.getInstance().versionName)
            } else if (oldVersion != GlobalMemoryControl.getInstance().versionName) {
                ParameterSetting.getInstance()
                    .setParameter("oldVersion", GlobalMemoryControl.getInstance().versionName)
                return
            }
        }

        //初始化通知栏操作
        initWakeLock()
        NotificationUtil.register(this)
        registerBroadcastReceiver()
        initNotification()

        //展示通知栏
        try {
            //定义通知来的layout
            customView = RemoteViews(service.packageName, R.layout.service_notification)

            //设置通知栏点击事件
            val broadcastIntent =
                PendingIntent.getBroadcast(
                    service,
                    0,
                    Intent(action),
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            //构建通知
            builder = NotificationCompat.Builder(service, channel)
                .setSmallIcon(R.drawable.notification_icon)
                .setStyle(NotificationCompat.DecoratedCustomViewStyle())
                .setCustomContentView(customView)
                .setContentIntent(broadcastIntent)
                .setAutoCancel(false)

            //开启前台服务
            service.startForeground(notificationId, builder.build())
            //刷新下通知栏数据
            NotificationUtil.update()
        } catch (e: Exception) {
            trackingAbnormalData(
                service,
                "notification-2:开启前台服务失败",
                ShowNotification::class.java.name
            )
            e.printStackTrace()
        }
    }

    /**
     * 停止通知栏
     */
    fun dismiss() {
        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) {
            return
        }
        service.stopForeground(true)
        NotificationUtil.unregister(this)
        service.unregisterReceiver(broadcastReceiver)
    }

    /**
     * 更新通知栏消息
     */
    override fun onUpdate() {
        if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || customView == null) {
            return
        }
        customView?.setTextViewText(
            R.id.tv_delivery,
            if (NotificationUtil.delivery > 999) "999+" else NotificationUtil.delivery.toString()
        )
        customView?.setTextViewText(
            R.id.tv_receive,
            if (NotificationUtil.receive > 999) "999+" else NotificationUtil.receive.toString()
        )
        customView?.setTextViewText(
            R.id.tv_timeout,
            if (NotificationUtil.timeout > 999) "999+" else NotificationUtil.timeout.toString()
        )
        //更新通知数据
        NotificationManagerCompat.from(service).notify(notificationId, builder.build())
    }

    /**
     * 返回app运行状态
     *
     * @param context context
     * @param packageName 要判断应用的包名
     * @return int 1:前台 0:APP未打开或在后台
     */
    private fun isAppAlive(context: Context, packageName: String = service.packageName): Int {
        val activityManager: ActivityManager = context
            .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val infoList: List<ActivityManager.RunningTaskInfo> = activityManager
            .getRunningTasks(5)

        // 判断程序是否在栈顶
        return try {
            when {
                infoList.isNullOrEmpty() -> 0
                infoList[0].topActivity?.packageName == packageName -> 1
                else -> 0
            }
        } catch (e: Exception) {
            0
        }
    }
}